<template>
	<view class="ui-popover" :class="popover ? 'show' : 'hide'">
		<view class="ui-popover-button" :class="[ui]" :id="'popover-button-' + _uid"
			:style="{ zIndex: index + sys_layer }" @tap="popoverClick" @mouseleave="mouseleave" @mouseover="mouseover">
			<slot></slot>
		</view>
		<view class="ui-popover-box" :style="BoxStyle">
			<view class="ui-popover-content-box" :id="'popover-content-' + _uid" :style="contentStyle">
				<view class="ui-popover-content radius text-a" :class="bg" :style="{ zIndex: index + sys_layer + 2 }">
					<view class="p-3 text-sm" v-if="tips">{{ tips }}</view>
					<block v-else>
						<slot name="content" />
					</block>
				</view>
				<view class="ui-popover-arrow" :class="bg" :style="arrowStyle"></view>
			</view>
		</view>
		<view class="ui-popover-mask" :class="mask ? 'bg-mask-50' : ''" :style="{ zIndex: index + sys_layer - 1 }"
			@tap="popover = false" v-if="(popover && tips == '' && time == 0) || mask"></view>
	</view>
</template>

<script>
	export default {
		name: 'UiPopover',
		data() {
			return {
				popover: false,
				BoxStyle: '',
				contentStyle: '',
				arrowStyle: '',
				button: {},
				content: {}
			};
		},
		props: {
			ui: {
				type: String,
				default: ''
			},
			tips: {
				type: String,
				default: ''
			},
			bg: {
				type: String,
				default: 'ui-BG'
			},
			mask: {
				type: Boolean,
				default: false
			},
			show: {
				type: [Boolean, String],
				default: 'change'
			},
			hover: {
				type: Boolean,
				default: false
			},
			index: {
				type: Number,
				default: 0
			},
			time: {
				type: Number,
				default: 0
			},
			bottom: {
				type: Boolean,
				default: false
			},
			isChange: {
				type: Boolean,
				default: false
			}
		},
		watch: {
			popover(val) {
				this._computedQuery(uni.getSystemInfoSync().windowWidth, uni.getSystemInfoSync().windowHeight);
				if (val) {
					if (this.tips != '' || this.time > 0) {
						setTimeout(
							() => {
								this.popover = false;
							},
							this.time == 0 ? 3000 : this.time
						);
					}
					this.sys_layer = this.sys_layer + 100;
				} else {
					this.sys_layer = this.sys_layer - 100;
				}
				this.$emit('update:show', val);
			},
			show(val) {
				this.popover = val;
			}
		},
		mounted() {
			this.$nextTick(() => {
				this._computedQuery(uni.getSystemInfoSync().windowWidth, uni.getSystemInfoSync().windowHeight);
				// #ifdef H5
				uni.onWindowResize(res => {
					this._computedQuery(res.size.windowWidth, res.size.windowHeight);
				});
				// #endif
			});
		},
		methods: {
			_onHide() {
				this.popover = false;
			},
			_computedQuery(w, h) {
				uni.createSelectorQuery()
					.in(this)
					.select('#popover-button-' + this._uid)
					.boundingClientRect(button => {
						if (button != null) {
							this.button = button;
						} else {
							console.log('popover-button-' + this._uid + ' data error');
						}
					})
					.select('#popover-content-' + this._uid)
					.boundingClientRect(content => {
						if (content != null) {
							this.content = content;
							let button = this.button;
							//contentStyle
							let contentStyle = '';
							let arrowStyle = '';
							this.BoxStyle =
								`width:${w}px; left:-${button.left}px;z-index: ${this.index + this.sys_layer + 102}`;
							// 判断气泡在上面还是下面
							if (button.bottom < h / 2 || this.bottom) {
								// '下';
								contentStyle = contentStyle + `top:10px;`;
								arrowStyle = arrowStyle + `top:${-5}px;`;
							} else {
								// '上';
								contentStyle = contentStyle + `bottom:${button.height + 10}px;`;
								arrowStyle = arrowStyle + `bottom:${-5}px;`;
							}

							// 判断气泡箭头在左中右
							let btnCenter = button.right - button.width / 2;
							let contentCenter = content.right - content.width / 2;
							if ((btnCenter < w / 3 && content.width > btnCenter) || (content.width > w / 2 &&
									btnCenter < w / 2)) {
								// '左';
								contentStyle = contentStyle + `left:10px;`;
								arrowStyle = arrowStyle + `left:${btnCenter - 17}px;`;
							} else if ((btnCenter > (w / 6) * 4 && content.width > w - btnCenter) || (content.width >
									w / 2 && btnCenter > w / 2)) {
								// '右';
								contentStyle = contentStyle + `right:10px;`;
								arrowStyle = arrowStyle + `right:${w - btnCenter - 17}px;`;
							} else {
								// '中';
								contentStyle = contentStyle +
									`left:${button.left - content.width / 2 + button.width / 2}px;`;
								arrowStyle = arrowStyle + `left:0px;right:0px;margin:auto;`;
							}

							this.arrowStyle = arrowStyle + `z-index:${this.index + this.sys_layer + 1};`;
							this.contentStyle = contentStyle + `z-index:${this.index + this.sys_layer + 2};`;
						} else {
							console.log('popover-content-' + this._uid + ' data error');
						}
					})
					.exec();
			},
			popoverClick() {
				if (this.isChange) {
					return false
				}
				if (this.tips == '') {
					this.popover = !this.popover;
				} else {
					this.popover = true;
				}
			},
			mouseover() {
				if (this.hover&&(this.tips!=''||this.content.height!=0)) {
					this.popover = true;
				}
			},
			mouseleave() {
				if (this.hover) {
					this.popover = false;
				}
			}
		}
	};
</script>

<style lang="scss">
	.ui-popover {
		position: relative;

		.ui-popover-button {
			position: relative;
		}

		.ui-popover-box {
			position: absolute;

			.ui-popover-content-box {
				position: absolute;

				.ui-popover-content {
					position: relative;
				}

				.ui-popover-arrow {
					position: absolute;
					height: 15px;
					width: 15px;
					border-radius: 2px;
					transform: rotate(45deg);
				}

				&::after {
					content: '';
					width: 100%;
					height: 110%;
					position: absolute;
					background-color: #000000;
					top: 5%;
					left: 0;
					filter: blur(15px);
					opacity: 0.15;
				}
			}
		}

		.ui-popover-mask {
			position: fixed;
			width: 100%;
			height: 100%;
			top: 0;
			left: 0;
		}

		&.show {
			.ui-popover-button {}

			.ui-popover-content-box {
				opacity: 1;
				pointer-events: auto;
			}

			.ui-popover-arrow {
				display: block;
			}

			.ui-popover-mask {
				display: block;
			}
		}

		&.hide {
			.ui-popover-button {}

			.ui-popover-content-box {
				opacity: 0;
				pointer-events: none;
			}

			.ui-popover-arrow {
				display: none;
			}

			.ui-popover-mask {
				display: none;
			}
		}
	}
</style>
